/**
 * 项目名：	Rumba Plan
 * 
 * 版权所有(C)，上海海鼎信息工程股份有限公司，2007，所有权利保留。
 * 
 * 文件名：	BOptionCollection.java
 * 模块说明：	
 * 修改历史：
 * 2007-3-20 - lxm - 创建。
 */
package com.hd123.rumba.option.biz;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;

import net.sf.hibernate.HibernateException;

import com.hd123.rumba.domain.CDomain;
import com.hd123.rumba.domain.IDomain;
import com.hd123.rumba.domain.IDomainMgr;
import com.hd123.rumba.exception.BusinessException;
import com.hd123.rumba.option.IOptionCollection;
import com.hd123.rumba.option.IOptionItem;
import com.hd123.rumba.option.IOptionMgr;
import com.hd123.rumba.option.IOptionalClassInfo;
import com.hd123.rumba.option.IOptionalClassInfoMgr;
import com.hd123.rumba.runtime.IPersistent;
import com.hd123.rumba.runtime.NamingMgr;
import com.hd123.rumba.runtime.biz.BBaseEntity;
import com.hd123.rumba.user.CUser;
import com.hd123.rumba.user.biz.SUser;

/**
 * 选项取值集合 | 业务层.维护 | 实体
 * <p>
 * 
 * 属性user的取值null与非null表示两种类型的选项取值：<br>
 * <li>==null，表示指定域的全局取值。</li>
 * <li>!=null，表示指定用户的个性化取值。</li>
 * 
 * @author lxm
 * 
 */
public class BOptionCollection extends BBaseEntity {

  private String optionalClassName;
  private SUser user = null;
  Boolean locked = null;
  Boolean online = null;
  private Boolean inherited = null;
  protected HashMap<String, Object> values = new HashMap<String, Object>();

  public void readFrom(IPersistent source) throws BusinessException {
    super.readFrom(source);
    if (source instanceof IOptionCollection) {
      this.optionalClassName = ((IOptionCollection) source).getOptionalClassName();
      this.user = null;
      if (((IOptionCollection) source).getUser() != null) {
        this.user = new SUser();
        this.user.readFrom(((IOptionCollection) source).getUser());
      }
      this.inherited = ((IOptionCollection) source).getInherited();
      this.values.clear();
      List<IOptionItem> items = ((IOptionCollection) source).getItems();
      for (int i = 0; i < items.size(); i++) {
        IOptionItem item = items.get(i);
        this.values.put(item.getName(), item.getValue());
      }

      if (this.user == null) {
        this.locked = ((IOptionCollection) source).getLocked();
        this.online = ((IOptionCollection) source).getOnline();
      } else {
        this.locked = null;
        this.online = null;
      }
    }
  }

  /**
   * 转换为业务引用字符串。
   * 
   * @return
   * @throws BusinessException
   */
  public String toBizString() throws BusinessException {
    StringBuffer sb = new StringBuffer();
    sb.append(this.optionalClassName);
    sb.append(" @ ");
    sb.append(CDomain.CAPTION_CLASS);
    sb.append(":");
    sb.append(this.domain.getNameCode());
    if (this.user != null) {
      sb.append(" & ");
      sb.append(CUser.CAPTION_CLASS);
      sb.append(":");
      sb.append(this.user.getNameCode());
    }
    return sb.toString();
  }

  /**
   * 取得符合指定条件，且有效的（即有值的）选项名。
   * 
   * @param nameLike
   *          指定选项名类似于条件，通配符位于右边。例如传入"item"，等价于运算"<i>选项名</i> like 'item%'"。
   * @return 返回所有符合条件的选项名列表，若没有找到符合条件的，则返回空的列表。
   * @throws BusinessException
   */
  public List<String> getNames(String nameLike) throws BusinessException {
    if (nameLike == null)
      nameLike = "";
    List<String> ret = new ArrayList<String>();
    for (String name : this.values.keySet())
      if (name.startsWith(nameLike))
        ret.add(name);
    return ret;
  }

  /**
   * 属性：是否从上级继承。<br>
   * 当取值为true的时候，表示所有items所包含的选项取值无效。<br>
   * 用户个性化的上级是域全局，而域全局的上级是系统（出厂设置）。
   */
  public Boolean getInherited() {
    return inherited;
  }

  public void setInherited(Boolean empty) {
    this.inherited = empty;
  }

  /**
   * 属性：是否锁定个性化设置。<br>
   * 当user==null时，表示是否禁止所有用户进行个性化设置的修改，为读写属性。<br>
   * 当user!=null时，表示是否被禁止对个性化设置的修改，为只读属性。
   */
  public Boolean getLocked() throws BusinessException, HibernateException {
    if (locked == null)
      this.refreshGlobalSetting();
    return locked;
  }

  public void setLocked(Boolean locked) throws BusinessException {
    if (this.user != null)
      throw new BusinessException("只是个个性化设置，试图对只读属性locked进行修改，");
    this.locked = locked;
  }

  /**
   * 属性：是否启用个性化设置。<br>
   * 当user==null时，表示所有用户个性化设置是否有效，为读写属性。<br>
   * 当user!=null时，表示当前个性化设置是否有效，为只读属性。
   */
  public Boolean getOnline() throws BusinessException, HibernateException {
    if (locked == null)
      this.refreshGlobalSetting();
    return online;
  }

  public void setOnline(Boolean online) throws BusinessException {
    if (this.user != null)
      throw new BusinessException("只是个个性化设置，试图对只读属性locked进行修改，");
    this.online = online;
  }

  /** 属性：对应选项类名 */
  public String getOptionalClassName() {
    return optionalClassName;
  }

  public void setOptionalClassName(String optionalClassName) {
    this.optionalClassName = optionalClassName;
  }

  /** 属性：所属用户 */
  public SUser getUser() {
    return user;
  }

  public void setUser(SUser user) {
    this.user = user;
  }

  /** 属性：包含的选项与取值。 */
  public HashMap<String, Object> getValues() {
    return values;
  }

  void refreshGlobalSetting() throws BusinessException, HibernateException {
    IOptionMgr optMgr = (IOptionMgr) NamingMgr.getInstance().lookupMgr(IOptionMgr.class);
    IDomainMgr dmMgr = (IDomainMgr) NamingMgr.getInstance().lookupMgr(IDomainMgr.class);
    IDomain domain = dmMgr.getDomain(this.domain.getUuid());
    IOptionCollection collection = optMgr.getCollectionByClass(domain, optionalClassName, null);
    if (collection != null) {
      this.locked = collection.getLocked();
      this.online = collection.getOnline();
    } else {
      IOptionalClassInfoMgr ociMgr = (IOptionalClassInfoMgr) NamingMgr.getInstance().lookupMgr(
          IOptionalClassInfoMgr.class);
      IOptionalClassInfo oci = ociMgr.getClassInfoByClass(this.optionalClassName);
      if (oci == null)
        throw new BusinessException("无法找到指定选项类(" + optionalClassName +")对应的选项信息。");
      this.locked = oci.getLocked();
      this.online = oci.getOnline();
    }
  }

}
